#pragma once
#include <iostream>
#include <unordered_map>
#include "Protocol.hpp"
#include "../Connection.hpp"
#include "Request&&Response.hpp"
#include "../RoomPlayers.hpp"

extern std::unordered_map<std::string, Room *> rooms;
extern std::unordered_map<int, std::string> fd_to_room_number;

class RequestQuitRoom : public Request
{
public:
    RequestQuitRoom() {}

    virtual bool Serialize(std::string *msg)
    {
        return true;
    }
    virtual bool Deserialize(const Json::Value &root)
    {
        return true;
    }

    ~RequestQuitRoom() {}

private:
};

class ResponseQuitRoom : public Response
{
public:
    ResponseQuitRoom() {}

    virtual bool Serialize(std::string *msg)
    {
        // Json::Value root;
        // root["return"] = _return;
        // Json::FastWriter writer;
        // *msg = writer.write(root);
        // // std::cout << *msg << std::endl;
        // _return  = 0;
        return true;
    }

    // 收到客户端发来的退出的请求时，服务器端需要向处在房间的其他人发送退出房间信号
    bool ServerHandler(const RequestQuitRoom *req, Connection *conn)
    {
        std::vector<Player> &players = rooms[fd_to_room_number[conn->GetFd()]]->GetPlayers();
        std::string msg;
        Json::Value root;
        root["server_type"] = QuitRoom;
        for (int i = 0; i < players.size(); i++)
        {
            if (players[i].Exist())
            {
                // std::cout << "i: " << i << std::endl;
                Connection *conn_player = players[i].GetConnection();
                if (conn == conn_player)
                {
                    root["player_id"] = i;
                    break;
                }
            }
        }
        Json::FastWriter writer;
        msg = writer.write(root);
        // std::cout << "quit room msg: " << msg;
        Package(msg, &msg);
        for (int i = 0; i < players.size(); i++)
        {
            if (players[i].Exist())
            {
                Connection *conn_player = players[i].GetConnection();
                if (conn != conn_player)
                {
                    conn_player->GetOutbuffer() += msg;
                    // std::cout << "conn_player->GetOutbuffer() " << conn_player->GetOutbuffer() << std::endl;
                    conn_player->GetWriter()(conn_player);
                }
            }
        }

        rooms[fd_to_room_number[conn->GetFd()]]->DelPlayer(conn);
        fd_to_room_number.erase(conn->GetFd());
        return true;
    }

    virtual bool Deserialize(const std::string &result)
    {
        return true;
    }

    virtual ~ResponseQuitRoom() {}

private:
    int _return = 0;
};
